import { _decorator, resources, TextAsset } from 'cc';

export class CSVData{
    private _datas = [];

    get Data(){
        return this._datas;
    }
    addData(data:any){
        this._datas.push(data);
    }
    getDataById(id:number|string){
        for (const data of this._datas) {
            if (data['id'] && data['id'] == id ) {
                return data;
            }
        }
        return null;
    }
    getDataByIndex(index:number){
        return this._datas[index];
    }
}

export class CSVManager{
    // 所有csv数据
    private _datas:Map<string,CSVData> = new Map();
    // 单例
    private static  _instance = null;
    public static get Instance():CSVManager{
        if (!this._instance) {
            this._instance = new CSVManager();
        }
        return this._instance;
    }
    /** 
    * @zh 解析CSV表格数据 
    * @zh 若第二个参数传入false 则解析后的数据不存储到管理器中，否则默认存储
    */
    public parseCSV(textAsset:TextAsset,saveData:boolean = true){
        // 读字符串
        const text = textAsset.text;
        // 以\n拆解总共有几行
        const lineInfo = text.split('\r\n');
        // 第0行 作为数据属性名  用,拆解
        const arrProName = lineInfo[0].split(',');
        // 去掉最后一个属性名的\r
        // arrProName[arrProName.length-1] = this.slice_r(arrProName[arrProName.length-1]);
        // 第1行 作为数据属性对应的数据类型  用,拆解
        const arrProType = lineInfo[1].split(',');
        // 去掉最后一个属性类型的\r
        // arrProType[arrProType.length-1] = this.slice_r(arrProType[arrProType.length-1]);
        // 创建第2行开始的数据 
        // 创建数据对象
        let csvData:CSVData = new CSVData();
        for(let i = 2;i < lineInfo.length-1;i++){
            let dataInfo = lineInfo[i].split(',');
            // 每行一个数据
            let data = {};
            // 第0个单元格没有数据
            for (let j = 1; j < dataInfo.length; j++) {
                let value = dataInfo[j];
                // if(value.endsWith('\r')){
                //     value = this.slice_r(value);
                // }
                let type = arrProType[j];
                let key = arrProName[j];
                this.setTypeAndVal(data,key,value,type);
            }
             // 存储当前数据
             csvData.addData(data);
        }
        // 存储当前csv
        if(saveData){
            this._datas.set(textAsset.name,csvData);
        }
        
        // 返回数据
        return csvData;
    }

     // 解析键值对数据对象 
    setTypeAndVal(data:any,key:string,val:string,type:string){
        let value:any = val;
        switch (type) {
            case 'number':
                value = Number(val);
                break;
            case 'boolean':
                value = Boolean(val);
                break;
            case 'arr_number':
                value = val.split(';');
                for(let i = 0;i < value.length;i++){
                    value[i] = Number(value[i]);
                }
                break;
            
            case 'arr_string':
                value = val.split(';');
                break;
        }
       data[key] = value;
    }

    // 通过id和csv名称获取数据
    getDataById(id:number|string,name?:string){
        if (name) {
            let csvData:CSVData =  this._datas.get(name);
            if (csvData) {
                return csvData.getDataById(id);
            }
        }
        let arr = Array.from(this._datas.values());
        for (const csvData of arr) {
            let data = csvData.getDataById(id);
            if (data) {
                return data;
            }
        }
        return null;
    }
    // 通过索引获取数据
    getDataByIndex(index:number,name?:string){
        if (name) {
            let csvData:CSVData = this._datas.get(name);
            if (csvData) {
                return csvData.getDataByIndex(index);
            }
        }
        let arr = Array.from(this._datas.values());
        for (const csvData of arr) {
            let data = csvData.getDataByIndex(index);
            if (data) {
                return data;
            }
        }
        return null;
    }
   
    // 去除\r
    slice_r(info:string):string{
        return info.slice(0,info.length-1);
    }

    // 异步加载资源
    private load(path:string){
        return new Promise((resolve, reject) => {
            resources.load(path, (err, res) => {
                if (err) {
                    reject(err);
                } else {
                    resolve(res);
                }
            });
        }); 
    }
    /**
     * @en load and get CSVData.
     * @zh 动态加载CSV 请使用async...await获取CSVData对象
     * @zh 若第二个参数传入false 则解析后的数据不存储到管理器中，否则默认存储
     */
    async loadCSV(path:string,saveData:boolean = true):Promise<CSVData> {
        try {
            const res = await this.load(path);
            console.log('CSV loaded:', res);
            // 在这里处理加载成功的资源
            const csv:TextAsset = res as TextAsset;
            return this.parseCSV(csv,saveData);
        } catch (error) {
            console.error('Error loading CSV:'+ path, error);
            // 在这里处理加载资源失败的情况
            return null;
        }
    }

    
}



